package com.test;

//import com.sun.jdi.StackFrame;

import java.io.File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.OutputStreamWriter;
import java.util.*;

/**
 * Created by IntelliJ IDEA.
 * User: adenysenko
 * Date: Apr 23, 2007
 * Time: 4:20:32 PM
 * To change this template use File | Settings | File Templates.
 */
public class ReadThreadDump {
  static List<String> httpThreads = new ArrayList<String>();
  static FrameStats stats = new FrameStats();

  public static void main(String[] args) throws Exception{
    File fcatalinaOut = new File("/proj/tmp/catalina.out.0930");
    BufferedReader br = new BufferedReader(new FileReader(fcatalinaOut));
    String line;
    for(;;){
      line = br.readLine();
      if( line.indexOf("thread dump")!=-1 ){
        line = br.readLine();
        if( line.equals("") ){
          break;
        }
      }
    }
    int i=0;
    while( readThread(br, ++i ) ){
    }

    System.out.println();
    System.out.println();

    Collections.sort( httpThreads , new Comparator<String>(){
      public int compare(String o1, String o2) {
        return Long.signum(parseTimeToken(o2)-parseTimeToken(o1));
      }
    });
    System.out.println("================");
    long max = parseTimeToken( httpThreads.get(0) );
    int ord=0;
    for( String t : httpThreads ){
      System.out.println( '#' + ord++ + " - "+ (max-parseTimeToken(t)) +"  "+t);
    }
    System.out.println("================");

    stats.print(new OutputStreamWriter(System.out));

  }

  static boolean readThread(BufferedReader br, int i) throws Exception{
    String line = br.readLine();
    if( !line.startsWith("\"") ){
      return false;
    }
    String head = line;
    int frames=0;
    List<String> framesList = new ArrayList<String>();
    while( (line=br.readLine()).length()>0 ){
      frames++;
      line = line.trim();
      if( line.startsWith("at ") ){
        framesList.add(line);
      }
    }
    Collections.reverse(framesList);

    FrameStats nestedStats = stats;
    for( String l : framesList ){
        nestedStats=nestedStats.recordNestedInvocation(l);
    }

    long time = parseTimeToken(head);
    if( time!=-1){
      httpThreads.add(head);
    }
    System.out.println(i+": "+frames+": "+time +" - " +head);

    return true;
  }

  public static long parseTimeToken(String s){
    StringTokenizer st = new StringTokenizer(s," ");
    while(st.hasMoreTokens()){
      String t = st.nextToken();
      if( t.startsWith("[T") && t.endsWith("]") ){
        try{
          //long tSecsSinceStart = (System.currentTimeMillis() - 0/*START*/)/1000;
          //return tSecsSinceStart - Long.parseLong(t.substring(2,t.length()-1));
          return Long.parseLong(t.substring(2,t.length()-1));
        }catch(Exception e){
        }
      }
    }
    return -1;
  }

}
